import logging
from urllib.parse import unquote, quote
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from dify.api import run_workflow, parse_workflow_response, DifyAPIError
from .models import PhaseSummary
from .serializers import (
    PhaseSummarySerializer, 
    PhaseSummaryCreateSerializer,
    PhaseSummaryListSerializer
)
from django.http import HttpResponse
import re
from docx.oxml.ns import qn
from docx.api import Document
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from utils.redis_helper import RedisHelper

logger = logging.getLogger('phase_summary')
class CustomPagination(PageNumberPagination):
    """自定义分页器"""
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 100

class PhaseSummaryViewSet(viewsets.ModelViewSet):
    """
    阶段总结视图集
    提供以下接口：
    - GET /api/v1/summary/?industry=xxx - 获取报告列表，支持按产业筛选
    - GET /api/v1/summary/{id}/ - 获取单个报告
    - POST /api/v1/summary/generate/ - 生成新报告
    - DELETE /api/v1/summary/{id}/ - 删除报告
    """
    queryset = PhaseSummary.objects.all()
    serializer_class = PhaseSummarySerializer
    pagination_class = CustomPagination

    def get_serializer_class(self):
        print(f"Current action: {self.action}")  # 打印当前action
        if self.action == 'list':
            return PhaseSummaryListSerializer
        elif self.action == 'generate':
            return PhaseSummaryCreateSerializer
        return PhaseSummarySerializer

    def get_queryset(self):
        """根据用户角色和查询参数过滤报告"""
        queryset = super().get_queryset()
        
        # 获取查询参数
        industry = self.request.query_params.get('industry', None)
        report_type = self.request.query_params.get('report_type', None)
        report_style = self.request.query_params.get('report_style', None)
        workflow_name = self.request.query_params.get('workflow_name', None)
        
        # 按产业过滤
        if industry:
            industry = unquote(industry)
            queryset = queryset.filter(industry__icontains=industry)
        
        # 按报告类型过滤
        if report_type:
            queryset = queryset.filter(report_type=report_type)
        
        # 按报告风格过滤
        if report_style:
            queryset = queryset.filter(report_style=report_style)
        
        # 按工作流名称过滤    
        if workflow_name:
            queryset = queryset.filter(workflow_name=workflow_name)
        
        # 如果不是超级用户，根据用户角色过滤报告风格
        user = self.request.user
        if not user.is_superuser:
            if user.identity == 'research':  # 科研院所只能看科研风格
                queryset = queryset.filter(report_style=3)
            elif user.identity == 'enterprise':  # 企业单位只能看创新风格
                queryset = queryset.filter(report_style=2)
            elif user.identity == 'government':  # 政府机关只能看决策风格
                queryset = queryset.filter(report_style=1)
        
        return queryset.order_by('-created_at')

    def list(self, request, *args, **kwargs):
        """获取报告列表"""
        try:
            queryset = self.get_queryset()
            total_count = queryset.count()
            page_size = int(request.query_params.get('page_size', 10))
            page_number = int(request.query_params.get('page', 1))
            total_pages = (total_count + page_size - 1) // page_size if total_count > 0 else 0

            # 如果查询结果为空，直接返回空数据
            if total_count == 0:
                return Response({
                    'code': 200,
                    'message': '查询内容为空',
                    'data': {
                        'results': [],
                        'count': 0,
                        'page_size': page_size,
                        'page_number': page_number,
                        'total_pages': 0
                    }
                })

            # 检查页码是否有效（只有在有数据时才检查）
            if page_number > total_pages and total_count > 0:
                return Response({
                    'code': 400,
                    'message': f'页码无效：当前数据共{total_count}条，每页{page_size}条，'
                              f'共{total_pages}页，请求的第{page_number}页不存在'
                }, status=status.HTTP_400_BAD_REQUEST)

            page = self.paginate_queryset(queryset)
            serializer = self.get_serializer(page, many=True)
            response = self.get_paginated_response(serializer.data)
            data = response.data
            
            return Response({
                'code': 200,
                'message': '获取成功',
                'data': data
            })

        except Exception as e:
            return Response({
                'code': 500,
                'message': f'获取列表失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def destroy(self, request, *args, **kwargs):
        """删除报告"""
        instance = self.get_object()
        self.perform_destroy(instance)
        return Response({
            'code': 200,
            'message': '删除成功'
        })

    @action(detail=False, methods=['post'])
    def generate(self, request):
        """生成新报告"""
        print(f"请求数据: {request.data}")  # 添加调试日志
        redis_helper = RedisHelper()
        cache_key = f"report_cache_{request.user.id}"
        
        # 检查缓存
        cached_data = redis_helper.get_value(cache_key)
        if cached_data:
            return Response(cached_data)
            
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        
        try:
            # 获取用户请求的报告风格
            report_style = serializer.validated_data.get('report_style', 0)
            report_type = serializer.validated_data.get('report_type', 0)
            style_text = {
            1: "决策风格",
            2: "创新风格",
            3: "科研风格"
        }.get(report_style, "科研风格")
            type_text = {
            1: "月度",
            2: "季度",
            3: "年度"
        }.get(report_type, "年度")
            original_context = serializer.validated_data['context']
            # 组合完整的context
            full_context = f"{original_context}{type_text}{style_text}"    
            # 如果不是超级用户，验证是否有权限生成该风格的报告
            if not request.user.is_superuser:
                user_style = None
                if request.user.identity == 'research':
                    user_style = 3  # 科研风格
                elif request.user.identity == 'enterprise':
                    user_style = 2  # 创新风格
                elif request.user.identity == 'government':
                    user_style = 1  # 决策风格
                    
                # 如果用户请求的风格与其角色不符，返回错误
                if report_style != user_style:
                    return Response({
                        'code': 403,
                        'message': '您没有权限生成该风格的报告'
                    }, status=status.HTTP_403_FORBIDDEN)
            
            # 调用Dify API生成报告
            response = run_workflow(
                workflow_name="阶段总结",
                inputs={
                    "context": full_context,
                    "user_id": str(request.user.id),
                },
                user=str(request.user.id)
            )
            
            content = parse_workflow_response(response)
            
            # 从内容中提取标题
            title = "阶段总结报告"
            lines = content.split('\n')
            for line in lines:
                if line.strip().startswith('###'):
                    title = line.strip().replace('###', '').strip()
                    break
            
            # 保存到数据库
            summary = PhaseSummary.objects.create(
                title=title,
                content=content,
                workflow_name=1,  # 阶段总结
                report_type=serializer.validated_data.get('report_type', 0),
                report_style=report_style,  
                industry=serializer.validated_data.get('industry', ''),
                user=request.user
            )
            
            # 创建响应数据
            response_data = {
                'code': 200,
                'message': '报告生成成功',
                'data': PhaseSummarySerializer(summary).data
            }
            
            # 设置缓存
            redis_helper.set_value(cache_key, response_data, expire=3600)  # 1小时过期
            
            return Response(response_data)
            
        except DifyAPIError as e:
            return Response({
                'code': 500,
                'message': f'生成服务调用失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        
        except Exception as e:
            return Response({
                'code': 500,
                'message': f'报告生成失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def retrieve(self, request, *args, **kwargs):
        """获取单个报告"""
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response({
            'code': 200,
            'message': '获取成功',
            'data': serializer.data
        })

    def process_report_content(self, content):
        """处理报告内容：移除markdown标记和多余空格"""
        # 移除 markdown 标记
        content = re.sub(r'#+\s*', '', content)  # 移除标题标记
        content = re.sub(r'\*\*', '', content)   # 移除加粗标记
        
        # 处理多余的空格和空行
        lines = content.split('\n')
        processed_lines = []
        
        for line in lines:
            # 跳过空行
            if not line.strip():
                continue
            # 处理每行内容
            processed_line = ' '.join(line.split())  # 移除多余空格
            processed_lines.append(processed_line)
        
        # 使用单个换行符连接所有行
        return '\n'.join(processed_lines)

    def process_markdown_to_docx(self, title, content):
        """将 markdown 内容转换为 docx 文档"""
        doc = Document()
        
        # 设置全局字体
        doc.styles['Normal'].font.name = '宋体'  # 设置中文字体
        doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')  # 设置中文字体
        doc.styles['Normal'].font.size = Pt(12)  # 设置正文字体大小
        
        # 设置标题
        title_para = doc.add_paragraph()
        title_run = title_para.add_run(title)
        title_run.font.size = Pt(16)
        title_run.font.bold = True
        title_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
        
        
        # 处理内容
        lines = content.split('\n')
        
        for line in lines:
            # 跳过空行
            if not line.strip():
                continue
            
            # 处理标题
            if line.startswith('###'):
                text = line.replace('###', '').strip()
                p = doc.add_paragraph()
                run = p.add_run(text)
                run.font.size = Pt(14)
                run.font.bold = True
            elif line.startswith('####'):
                text = line.replace('####', '').strip()
                p = doc.add_paragraph()
                run = p.add_run(text)
                run.font.size = Pt(12)
                run.font.bold = True
            # 处理列表
            elif line.strip().startswith('- '):
                text = line.strip()[2:]  # 移除"- "
                p = doc.add_paragraph(style='List Bullet')
                # 移除markdown加粗标记
                text = re.sub(r'\*\*(.*?)\*\*', r'\1', text)
                p.add_run(text)
            # 普通段落
            else:
                p = doc.add_paragraph()
                # 移除markdown加粗标记
                text = re.sub(r'\*\*(.*?)\*\*', r'\1', line.strip())
                p.add_run(text)
        
        return doc

    @action(detail=True, methods=['get'])
    def download(self, request, pk=None):
        """下载报告为文本文档"""
        try:
            logger.info(f"开始处理下载请求，用户: {request.user.username}, 报告ID: {pk}")
            summary = self.get_object()
            
            # 检查权限：非超级用户只能下载对应风格的报告
            if not request.user.is_superuser:
                user_style = None
                if request.user.identity == 'research':
                    user_style = 3  # 科研风格
                elif request.user.identity == 'enterprise':
                    user_style = 2  # 创新风格
                elif request.user.identity == 'government':
                    user_style = 1  # 决策风格
                
                logger.info(f"用户身份检查 - 用户类型: {request.user.identity}, 用户风格: {user_style}, 报告风格: {summary.report_style}")
                    
                if summary.report_style != user_style:
                    logger.warning(f"权限拒绝 - 用户: {request.user.username} 尝试下载不匹配风格的报告")
                    return Response({
                        'code': 403,
                        'message': '您没有权限下载该风格的报告'
                    }, status=status.HTTP_403_FORBIDDEN)

            # 处理文档内容
            processed_content = self.process_report_content(summary.content)
            
            
            filename = f"{summary.title}.txt"
            
            # 创建响应
            response = HttpResponse(processed_content, content_type='text/plain; charset=utf-8')
            response['Content-Disposition'] = f'attachment; filename="{filename}"'
            
            logger.info(f"文档下载处理完成，文件名: {filename}")
            return response
                
        except Exception as e:
            logger.error(f"下载失败 - 用户: {request.user.username}, 报告ID: {pk}", exc_info=True)
            return Response({
                'code': 500,
                'message': f'下载失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        
    @action(detail=False, methods=['post'])
    def geneall(self, request):
        """
        批量生成报告
        请求体示例：
        {
            "industries": [
                {"name": "碳纤维", "keyword": "轻量化"},
                {"name": "人工智能", "keyword": "机器学习"}
            ]
        }
        """
        try:
            industries = request.data.get('industries', [])
            if not industries:
                return Response({
                    'code': 400,
                    'message': 'industries 字段不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 限制最多处理 10 个产业
            if len(industries) > 10:
                industries = industries[:10]

            # 定义报告风格和时间段
            report_styles = [
                {"id": 1, "name": "决策风格"},
                {"id": 2, "name": "创新风格"},
                {"id": 3, "name": "科研风格"}
            ]
            report_types = [
                {"id": 1, "name": "月度"},
                {"id": 2, "name": "季度"},
                {"id": 3, "name": "年度"}
            ]

            # 遍历每个产业
            for industry in industries:
                industry_name = industry.get('name')
                keyword = industry.get('keyword')

                if not industry_name or not keyword:
                    continue  # 跳过无效的产业数据

                # 遍历每种风格和时间段
                for style in report_styles:
                    for report_type in report_types:
                        try:
                            # 构造请求数据
                            data = {
                                "context": f"{industry_name} {keyword}",
                                "report_style": style['id'],
                                "report_type": report_type['id'],
                                "industry": industry_name
                            }

                            # 模拟请求对象
                            from rest_framework.test import APIRequestFactory
                            factory = APIRequestFactory()
                            mock_request = factory.post('/generate/', data, format='json')
                            mock_request.user = request.user  # 设置当前用户

                            # 调用 generate 方法
                            response = self.generate(mock_request)

                            # 检查生成结果
                            if response.status_code != status.HTTP_200_OK:
                                logger.error(f"生成报告失败 - 产业: {industry_name}, 关键词: {keyword}, 风格: {style['name']}, 时间段: {report_type['name']}")
                                continue  # 跳过当前报告，继续生成下一个

                        except Exception as e:
                            logger.error(f"生成报告失败 - 产业: {industry_name}, 关键词: {keyword}, 风格: {style['name']}, 时间段: {report_type['name']}", exc_info=True)
                            continue  # 跳过当前报告，继续生成下一个

            return Response({
                'code': 200,
                'message': '报告批量生成成功'
            })

        except Exception as e:
            logger.error("报告批量生成失败", exc_info=True)
            return Response({
                'code': 500,
                'message': f'报告批量生成失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)